package pl.javarsovia.javarsovia4android.util;

import static java.util.Arrays.*;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.util.ByteArrayBuffer;

import pl.javarsovia.R;
import pl.javarsovia.javarsovia4android.domain.Speaker;
import android.content.Context;
import android.graphics.drawable.Drawable;

public class ImageManager {

	static Map<String, Drawable> cache = new HashMap<String, Drawable>();
	private final Context ctx;
	private static ImageManager instance;

	private ImageManager(Context ctx) {
		this.ctx = ctx;
	}

	private static String getFileName(String photoUrl) {
		return photoUrl.substring(photoUrl.lastIndexOf('/') + 1);

	}

	public static ImageManager getInstance() {
		return instance;
	}

	public void downloadSpeakersPhotos(List<Speaker> speakers) {
		for (Speaker speaker : speakers) {
			String photoUrl = getPhotoUrl(speaker);
			String fileName = getFileName(photoUrl);
			if (fileIsUnavailable(fileName))
				downloadAndSaveFile(photoUrl, fileName);
		}

	}

	private String getPhotoUrl(Speaker speaker) {
		return "http://javarsovia.pl/" + speaker.getPhotoUrl();
	}

	private boolean fileIsUnavailable(String fileName) {
		return asList(ctx.fileList()).contains(fileName) == false;
	}

	public static ImageManager createInstanceFor(Context ctx) {
		instance = new ImageManager(ctx);
		return instance;
	}

	void downloadAndSaveFile(String photoUrl, String fileName) {
		try {
			ByteArrayBuffer baf = downloadFile(photoUrl);
			saveFile(fileName, baf);
		} catch (IOException e) {
			throw new RuntimeException("Can not download file", e);
		}

	}

	private ByteArrayBuffer downloadFile(String photoUrl) throws MalformedURLException, IOException {
		URL url = new URL(photoUrl);
		URLConnection conn = url.openConnection();

		InputStream is = conn.getInputStream();
		BufferedInputStream bis = new BufferedInputStream(is);

		ByteArrayBuffer baf = new ByteArrayBuffer(50);
		int current = 0;
		while ((current = bis.read()) != -1)
			baf.append((byte) current);
		return baf;
	}

	private void saveFile(String fileName, ByteArrayBuffer baf) throws FileNotFoundException, IOException {
		FileOutputStream fos = ctx.openFileOutput(fileName, Context.MODE_PRIVATE);
		fos.write(baf.toByteArray());
		fos.close();
	}

	public void loadAllPhotos() {
		for (String file : ctx.fileList())
			cache.put(file, openImage(file));
	}

	Drawable openImage(String file) {
		try {
			FileInputStream stream = ctx.openFileInput(file);
			Drawable image = Drawable.createFromStream(stream, "");
			cache.put(file, image);
			return image;
		} catch (Exception ex) {
			throw new RuntimeException("can not open file", ex);
		}
	}

	public Drawable getImage(String url) {
		Drawable image = cache.get(getFileName(url));
		if (image == null)
			return ctx.getResources().getDrawable(R.drawable.speaker_default_photo);
		return image;
	}
}